#include "mem_test.h"
#include "kmem.h"
#include "lib.h"
#include "serial.h"


#define BLOCK_SIZE 1024

//zweimaliges holen und wieder freigeben von 1KB-Grossen bloecken.
void 
mt_test1()
{
#define MAX 4000
    void* pointers[MAX];
    int i;

    kprintf("\nTest 1: \n\r"
           "Alloziere 4000 1KB-Grosse Speicherstucke (=4MB)\n\r");
    for(i=0; i < MAX;i++){
        pointers[i] = kmalloc( BLOCK_SIZE );
        if(!pointers[i]) {
	  kprintf("Fehler:\n\r konnte Block %i nicht allozieren\n\r",i);
	   while(1);
	}
    }

    kprintf("Gebe alle Bloecke wieder frei\n\r");
    for(i=0; i < MAX;i++){
        kfree( pointers[i], BLOCK_SIZE );
    }

    kprintf("Alloziere nochmals 4000 1KB-Grosse Bloecke (=4MB) \n \r");
    for(i=0; i < MAX;i++){
        pointers[i] = kmalloc( BLOCK_SIZE );
        if(!pointers[i]) { 
            kprintf("Fehler:\n\r konnte Block %i nicht allozieren\n\r",i);
	     while(1);
	}
    }

    kprintf("Gebe alle Bloecke wieder frei\n\r");
    for(i=0; i < MAX;i++){
        kfree( pointers[i], BLOCK_SIZE );
    }

    kprintf("Speichertest 1 erflogreich abgeschlossen\n\r");
#undef MAX
}

int 
mt_has_value(void* block, unsigned int size, char value)
{
    char* tmp = (char*)block;
    unsigned int i;
    for(i=0; i < size; i++){
        if(value != tmp[i]) return 0;
    }
    return 1;
}

void 
mt_test2()
{
#define MAX 100
#define VALUE1 1
#define VALUE2 2

    void* pointers[MAX];
    int i;
    
    kprintf("\nTest 2: \n\r");
    kprintf("reserviere 100 1KB-Blocke\n\r");
    for(i=0; i < MAX;i++){
        pointers[i] = kmalloc( BLOCK_SIZE );
        if(!pointers[i]){ 
            kprintf("Fehler:\n\r konnte Block %i nicht allozieren\n\r",i);
	     while(1);
	} 
    }

    kprintf("Fuer jeden Block trage beliebigen Wert ein\n und ueberpruefe, ob Bloecke sich nicht ueberlappen\n\r");
    for(i=0; i < MAX; i++){
        //fuelle zu testenden Block
        memset(pointers[i], VALUE1, BLOCK_SIZE);

        //fuelle alle anderen Bloecke
        int j=0;
        for(; j < MAX; j++){
            if(i == j) continue;
            memset(pointers[j], VALUE2, BLOCK_SIZE);
        }

        //teste ob aktueller Block nicht gueltig ist, oder
        //aus versehen ueberschrieben wurde
        if(!mt_has_value(pointers[i], BLOCK_SIZE, VALUE1)){ 
            kprintf("Fehler:\r\n Speicherbloecke ueberlappen sich\n\r",i);
	     while(1);
	}
    }

    kprintf("Gebe alle Bloecke wieder frei\n\r");
    for(i=0; i < MAX;i++){
        kfree( pointers[i], BLOCK_SIZE );
    }

    kprintf("Speichertest 2 erflogreich abgeschlossen\n\r");

#undef MAX
#undef VALUE1
#undef VALUE2
}

void 
mem_test()
{

    kprintf("Speichertest\n\r============\n\n\r");

    mt_test1();
    kprintf("\n");
    mt_test2();

    kprintf("Speichertest erflogreich abgeschlossen\n\r");
}

